//
// Created on 2024/11/22.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include "ui_attributes_capi.h"
#include "common/common.h"
#include <arkui/native_animate.h>
#include <arkui/native_interface.h>
#include <cstdint>
#include <string>
#include <sstream>

namespace ArkUICApiDemo {

static ArkUI_AnimatorHandle animatorHandle = nullptr;
static ArkUI_AnimatorOption *animatorOption = nullptr;
static ArkUI_NativeAnimateAPI_1 *animateApi = nullptr;
static int NUMBER_1000 = 1000;
static int NUMBER_3000 = 3000;

static auto CreateBaseButton(ArkUI_NativeNodeAPI_1 *nodeAPI, std::string& componentId)
{
    auto baseButton = nodeAPI->createNode(ARKUI_NODE_BUTTON);
    ArkUI_NumberValue width_value[] = {{.f32 = SIZE_100}};
    ArkUI_AttributeItem width_item = {width_value, sizeof(width_value) / sizeof(ArkUI_NumberValue)};
    nodeAPI->setAttribute(baseButton, NODE_WIDTH, &width_item);
    nodeAPI->setAttribute(baseButton, NODE_HEIGHT, &width_item);
    ArkUI_AttributeItem button_item = {nullptr, 0, "button"};
    nodeAPI->setAttribute(baseButton, NODE_BUTTON_LABEL, &button_item);
    ArkUI_AttributeItem idStr;
    idStr.string = componentId.c_str();
    nodeAPI->setAttribute(baseButton, NODE_ID, &idStr);
    ArkUI_NumberValue background_color_value[] = {{.u32 = COLOR_GREEN}};
    ArkUI_AttributeItem background_color_item = {background_color_value,
        sizeof(background_color_value) / sizeof(ArkUI_NumberValue)};
    nodeAPI->setAttribute(baseButton, NODE_BACKGROUND_COLOR, &background_color_item);
    return baseButton;
}

namespace AttributesCapi {
static ArkUI_NodeHandle buttonCom;
static void OnEventReceive(ArkUI_NodeEvent *event)
{
    if (event == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "AttributesCapiTest", "OnEventReceive: event is null");
        return;
    }
    int32_t eventId = OH_ArkUI_NodeEvent_GetTargetId(event);
    ArkUI_NativeNodeAPI_1 *nodeAPI = nullptr;
    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
    if (eventId == ON_CLICK_EVENT_ID) {
        ArkUI_ContextHandle context = OH_ArkUI_GetContextByNode(AttributesCapi::buttonCom);
        animatorHandle = animateApi->createAnimator(context, animatorOption);
        OH_ArkUI_Animator_Play(animatorHandle);
    }
}
} // namespace AttributesCapi

static void CreateAnimatorOption(bool enabled)
{
    animatorOption = OH_ArkUI_AnimatorOption_Create(PARAM_0);
    OH_ArkUI_AnimatorOption_SetDuration(animatorOption, NUMBER_3000);
    OH_ArkUI_AnimatorOption_SetBegin(animatorOption, PARAM_1);
    OH_ArkUI_AnimatorOption_SetEnd(animatorOption, PARAM_3);
    OH_ArkUI_AnimatorOption_SetDelay(animatorOption, NUMBER_1000);
    if (enabled) {
        OH_ArkUI_Curve_CreateCurveByType(ARKUI_CURVE_LINEAR);
        OH_ArkUI_AnimatorOption_SetIterations(animatorOption, PARAM_2);
    } else {
        OH_ArkUI_Curve_CreateCurveByType(ARKUI_CURVE_EASE_IN);
        OH_ArkUI_AnimatorOption_SetDirection(animatorOption, ARKUI_ANIMATION_DIRECTION_REVERSE);
    }
    OH_ArkUI_AnimatorOption_RegisterOnFrameCallback(animatorOption, nullptr, [](ArkUI_AnimatorOnFrameEvent *event){
        if (event == nullptr) {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "AnimatorRegisterOnFrame",
                "OnEventReceive: event is null");
            return;
        }

        ArkUI_NativeNodeAPI_1 *nodeAPI = nullptr;
        OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
        float progress = OH_ArkUI_AnimatorOnFrameEvent_GetValue(event);
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "OH_ArkUI_AnimatorOption", "progress %{public}f", progress);
        ArkUI_NumberValue widthValue[] = {progress * SIZE_100};
        ArkUI_AttributeItem widthItem = {widthValue, PARAM_1};
        nodeAPI->setAttribute(AttributesCapi::buttonCom, NODE_HEIGHT, &widthItem);
        nodeAPI->setAttribute(AttributesCapi::buttonCom, NODE_WIDTH, &widthItem);
    });
}

void UIAttrsCapi::CreateNativeNodeUIAttributesCapi0231(ArkUI_NativeNodeAPI_1 *nodeAPI, ArkUI_NodeHandle& rootNode)
{
    rootNode = nodeAPI->createNode(ARKUI_NODE_COLUMN);
    std::string componentId = "NODE_BUTTON_ATTRIBUTES_CAPI_0231";
    AttributesCapi::buttonCom = CreateBaseButton(nodeAPI,componentId);
    nodeAPI->registerNodeEvent(AttributesCapi::buttonCom, NODE_ON_CLICK, ON_CLICK_EVENT_ID, nullptr);
    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_ANIMATE, ArkUI_NativeAnimateAPI_1, animateApi);
    bool enable = true;
    CreateAnimatorOption(enable);
    nodeAPI->registerNodeEventReceiver(&AttributesCapi::OnEventReceive);
    nodeAPI->addChild(rootNode, AttributesCapi::buttonCom);
}

void UIAttrsCapi::CreateNativeNodeUIAttributesCapi0232(ArkUI_NativeNodeAPI_1 *nodeAPI, ArkUI_NodeHandle& rootNode)
{
    rootNode = nodeAPI->createNode(ARKUI_NODE_COLUMN);
    std::string componentId = "NODE_BUTTON_ATTRIBUTES_CAPI_0232";
    AttributesCapi::buttonCom = CreateBaseButton(nodeAPI,componentId);
    nodeAPI->registerNodeEvent(AttributesCapi::buttonCom, NODE_ON_CLICK, ON_CLICK_EVENT_ID, nullptr);
    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_NODE, ArkUI_NativeNodeAPI_1, nodeAPI);
    OH_ArkUI_GetModuleInterface(ARKUI_NATIVE_ANIMATE, ArkUI_NativeAnimateAPI_1, animateApi);
    bool enable = false;
    CreateAnimatorOption(enable);
    nodeAPI->registerNodeEventReceiver(&AttributesCapi::OnEventReceive);
    nodeAPI->addChild(rootNode, AttributesCapi::buttonCom);
}

}